package com.wy.multilevelpulldown;

import android.content.Context;
import android.database.DataSetObserver;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

import androidx.annotation.Nullable;

import java.util.ArrayList;
import java.util.List;

/**
 * Time:8/30/21
 * Author:ypf
 * Description:
 */
public class ListPopuScreenMenuView extends LinearLayout implements View.OnClickListener, Animation.AnimationListener {


    /**
     * 日志标签
     */
    private final String TAG = "ListPopuScreenMenuView";

    /**
     * 上下文
     */
    private Context context;

    /**
     * tab视图
     */
    private LinearLayout mTabMenuView;

    private DataSetObserver mDataSetObserver;

    private MenuObserver mMenuObserver;

    /**
     * 菜单视图
     */
    private FrameLayout mMenuContainerView;

    private View mMaskView;

    private MenuBaseAdapter mAdapter;

    /**
     * 当前tab点击的位置
     */
    protected int mCurrentPosition = -1;

    /**
     * 动画是否正在执行
     */
    private boolean mAnimationExcute = false;

    /**
     * tab集合
     */
    private List<View> mTabViews = new ArrayList<>();

    public ListPopuScreenMenuView(Context context) {
        this(context, null, 0);
    }

    public ListPopuScreenMenuView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ListPopuScreenMenuView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        initAttribute(attrs);
        initLayout();
    }

    private void initAttribute(AttributeSet attrs) {
        // TODO 设置自定义属性
    }

    private void initLayout() {

        // 垂直排列
        setOrientation(VERTICAL);

        // 初始化tabMenuView并添加到this
        mTabMenuView = new LinearLayout(context);
        LayoutParams params = new LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        mTabMenuView.setOrientation(HORIZONTAL);
        mTabMenuView.setBackgroundResource(R.drawable.menu_tab_bg);
        mTabMenuView.setLayoutParams(params);
        addView(mTabMenuView);

        // 菜单视图+阴影视图
        FrameLayout mMiddleView = new FrameLayout(context);
        mMiddleView.setLayoutParams(new FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.MATCH_PARENT,
                FrameLayout.LayoutParams.MATCH_PARENT));
        addView(mMiddleView);

        // 先初始化遮罩半透明View
        mMaskView = new View(getContext());
        mMaskView.setLayoutParams(new FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.MATCH_PARENT,
                FrameLayout.LayoutParams.MATCH_PARENT));
        mMaskView.setBackgroundColor(0x88888888);
        mMaskView.setOnClickListener(this);
        mMiddleView.addView(mMaskView);
        mMaskView.setVisibility(GONE);

        // 后初始化containerView并将其添加到mMiddleView
        mMenuContainerView = new FrameLayout(context);
        mMenuContainerView.setLayoutParams(new FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.MATCH_PARENT,
                FrameLayout.LayoutParams.MATCH_PARENT));
        mMiddleView.addView(mMenuContainerView);
        mMenuContainerView.setBackgroundColor(Color.WHITE);
        mMenuContainerView.setVisibility(GONE);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //设置菜单的高度
        int menuContainerHeight = MeasureSpec.getSize(heightMeasureSpec) * 75 / 100;
        if (menuContainerHeight != 0 && mMenuContainerView.getHeight() <= 0) {
            // 高度占整个父View的75%
            mMenuContainerView.getLayoutParams().height = menuContainerHeight;
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
    }

    @Override
    public void onClick(View v) {

    }

    /**
     * 添加Tab头部
     *
     * @param tabView
     */
    public void addTabView(View tabView) {
        mTabMenuView.addView(tabView);
        LayoutParams tabParams = (LayoutParams) tabView.getLayoutParams();
        // 权重设为1，每个子View占的宽度一样的
        tabParams.weight = 1;
        // 设置Tag就知道我点击的是哪一个位置
        tabView.setTag(mTabViews.size());
        Log.i(TAG, "tag->" + mTabViews.size());
        // 把tabView存入到列表中，当点击的时候就可以根据位置取出来
        mTabViews.add(tabView);
        switchTabViewClick(tabView);
    }

    /**
     * 添加菜单View
     */
    public void addMenuView(View menuView) {
        mMenuContainerView.addView(menuView);
        menuView.setVisibility(GONE);
    }

    private void switchTabViewClick(final View tabView) {

        tabView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // 动画是否执行完毕
                if (mAnimationExcute) return;
                // 根据tag拿到点击的位置
                int clickPosition = (int) tabView.getTag();
                // 处理点击
                tabClick(clickPosition, tabView);
            }
        });
    }

    /**
     * 头部点击
     */
    private void tabClick(int position, View tabView) {

        if (mCurrentPosition == position) {
            // 如果当前点击的位置 == 之前点击的位置 关闭菜单，mCurrentPosition置为-1
            closeMenu(tabView);
        } else {
            if (mCurrentPosition == -1) {
                // 显示当前的菜单
                mMenuContainerView.getChildAt(position).setVisibility(VISIBLE);
                // 打开菜单
                openMenu(tabView, position);
            } else {
                //关闭之前的菜单
                if (mAdapter != null)
                    mAdapter.overrideCloseMenu(mTabMenuView.getChildAt(mCurrentPosition));
                // 如果菜单是打开的改变布局
                exchangeLayout(position);
            }
            // 当前位置 == 点击位置
            mCurrentPosition = position;
            Log.i(TAG, "mCurrentPosition->" + mCurrentPosition);
            //打开现在的菜单
            if (mAdapter != null)
                mAdapter.overrideOpenMenu(mTabMenuView.getChildAt(mCurrentPosition), mCurrentPosition);
        }
    }

    // 菜单是否打开
    protected boolean mMenuIsOpen = false;

    /**
     * 关闭菜单
     */
    public void closeMenu(View tabView) {

        mMenuIsOpen = false;
        mMenuContainerView.setVisibility(View.GONE);
        mMaskView.setVisibility(GONE);
        Animation menuOutAnimation = AnimationUtils.loadAnimation(context, R.anim.dd_menu_out);
        Animation maskOutAnimation = AnimationUtils.loadAnimation(context, R.anim.dd_mask_out);
        menuOutAnimation.setAnimationListener(this);
        mMenuContainerView.setAnimation(menuOutAnimation);
        mMaskView.setAnimation(maskOutAnimation);
        //关闭之前的菜单
        if (mAdapter != null)
            mAdapter.overrideCloseMenu(tabView);
    }

    /**
     * 关闭菜单
     */
    public void openMenu(View tabView, int position) {
        mMenuIsOpen = true;
        mMenuContainerView.setVisibility(View.VISIBLE);
        mMaskView.setVisibility(VISIBLE);
        Animation menuOutAnimation = AnimationUtils.loadAnimation(context, R.anim.dd_menu_in);
        Animation maskOutAnimation = AnimationUtils.loadAnimation(context, R.anim.dd_mask_in);
        menuOutAnimation.setAnimationListener(this);
        mMenuContainerView.setAnimation(menuOutAnimation);
        mMaskView.setAnimation(maskOutAnimation);
    }

    /**
     * 改变显示布局
     */
    private void exchangeLayout(int position) {
        mMenuContainerView.getChildAt(position).setVisibility(VISIBLE);
        mMenuContainerView.getChildAt(mCurrentPosition).setVisibility(GONE);
    }

    /**
     * 动画开始执行
     */
    @Override
    public void onAnimationStart(Animation animation) {
        mAnimationExcute = true;
    }

    /**
     * 动画结束
     */
    @Override
    public void onAnimationEnd(Animation animation) {
        mAnimationExcute = false;
        if (!mMenuIsOpen) {
            // 如果是关闭菜单，隐藏当前menuView
            mMenuContainerView.getChildAt(mCurrentPosition).setVisibility(GONE);
            // 当前位置 == -1
            mCurrentPosition = -1;
        }
    }

    /**
     * 动画重复
     */
    @Override
    public void onAnimationRepeat(Animation animation) {
        mAnimationExcute = true;
    }

    /**
     * 设置View适配器
     */
    public void setAdapter(MenuBaseAdapter adapter) {

        if (adapter == null) {
            throw new NullPointerException("adapter is null...");
        }

        if (mAdapter != null) {
            mAdapter.unregisterDataSetObserver(mDataSetObserver);
            mAdapter = null;
            mTabMenuView.removeAllViews();
            mMenuContainerView.removeAllViews();
            mTabViews.clear();
        }

        if (mAdapter != null) {
            mAdapter.unregisterDataSetObserver(mMenuObserver);
            mAdapter = null;
        }

        this.mAdapter = adapter;

        mDataSetObserver = new DataSetObserver() {
            @Override
            public void onChanged() {
                resetLayout();
            }
        };

        //注册观察者 具体的观察者实例对象 订阅
        mAdapter.registerDataSetObserver(mDataSetObserver);

        mMenuObserver = new MenuObserver() {
            @Override
            public void closeMenu() {
                ListPopuScreenMenuView.this.closeMenu(mTabMenuView.getChildAt(mCurrentPosition));
            }

        };

        mAdapter.registerDataSetObserver(mMenuObserver);

        resetLayout();
    }

    private void resetLayout() {

        mTabMenuView.removeAllViews();
        mMenuContainerView.removeAllViews();
        mTabViews.clear();

        int count = mAdapter.getCount();
        for (int index = 0; index < count; index++) {
            // 添加Tab
            View childTabView = mAdapter.getTabView(index, mTabMenuView, this);
            if (childTabView != null) {
                addTabView(childTabView);
            }
            // 添加menu
            View childMenuView = mAdapter.getMenuView(index, mMenuContainerView, this);
            if (childMenuView != null) {
                addMenuView(childMenuView);
            }
        }

    }

}